package com.wydpp.gb28181.commander;

import cn.hutool.core.util.StrUtil;
import com.wydpp.properties.SystemProperties;
import com.wydpp.utils.ZlmUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class FfmpegCommander implements IFfmpegCommander {

    @Autowired
    private SystemProperties systemProperties;

    private static final Map<String, Process> processMap = new ConcurrentHashMap<>();

    /**
     * @param callId 会话id
     * @param stream 推流地址
     * @param ip     推流ip
     * @param port   推流端口
     * @return
     */
    public String pushStream(String callId, String stream, String ip, int port) {

        Map map = ZlmUtils.openRtpServer(callId);

        String command = systemProperties.getFfmpegPath() + " " +
                systemProperties.getFfmpegPushStreamCmd().replace("{stream}", stream).replace("{ip}", map.get("ip").toString()).replace("{port}", map.get("port") + "");

        log.info("callId={},\r\n推流命令={}", callId, command);
        Runtime runtime = Runtime.getRuntime();
        try {
            String finalCommand = command;
            new Thread(() -> {

                int code = 0;
                try {
                    Process process = runtime.exec(finalCommand);
                    processMap.put(callId, process);
                    InputStream errorInputStream = process.getErrorStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(errorInputStream));
                    StringBuffer errorStr = new StringBuffer();
                    String str;
                    while ((str = reader.readLine()) != null) {
                        errorStr.append(str);
                    }
                    code = process.waitFor();
                    log.info("推流已结束,callId={}", callId);
                } catch (Exception e) {
                    log.error("ffmpeg推流异常!", e);
                }
                System.out.println(code);
            }).start();

            Thread.sleep(5000);

            new Thread(() -> {
                ZlmUtils.startSendRtp(callId,ip,port);
            }).start();
            return command;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    public void closeStream(String callId) {
        log.info("关闭推流:{}", callId);
        if (StrUtil.isEmpty(callId)) {
            closeAllStream(callId);
        } else if (processMap.containsKey(callId)) {
            processMap.get(callId).destroy();
        } else {
            log.info("没有推流要关闭!");
        }
    }

    public void closeAllStream(String streamId) {
        log.info("关闭所有推流");
        processMap.entrySet().stream().forEach(entry -> {
            entry.getValue().destroy();
        });

        ZlmUtils.closeRtpServer(streamId);
    }
}
